#pragma once
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include<unistd.h>
#include"inet_addr.hpp"

#define default_fd -1
class UdpClient{
    public:
        UdpClient(const std::string ip,uint16_t port):_ip(ip),_port(port),_socketfd(default_fd){
            _socketfd = socket(AF_INET, SOCK_DGRAM, 0);
            if(_socketfd == -1){
                std::cout<<"Error in creating socket"<<std::endl;
                return;
            }
            memset(&_serveraddr,0,sizeof(sockaddr));
            _serveraddr.sin_family=AF_INET;
            _serveraddr.sin_port=htons(_port);
            _serveraddr.sin_addr.s_addr=inet_addr(_ip.c_str());
            if(connect(_socketfd,(struct sockaddr*)&_serveraddr,sizeof(_serveraddr))==-1){
                std::cout<<"连接失败"<<std::endl;
                perror("connect failed");
                close(_socketfd);
                _socketfd=default_fd;
                return;
            }
            std::cout<<"连接成功"<<std::endl;
        }
        std::string Recv(){
            char buffer[1024];
            memset(buffer,0,sizeof(buffer));
            struct sockaddr_in clientaddr;
            socklen_t addrlen=sizeof(clientaddr);
            memset(&clientaddr,0,addrlen);
            ssize_t n=recvfrom(_socketfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&clientaddr,&addrlen);
            if(n==-1){
                std::cout<<"读取错误"<<std::endl;
                perror("recvfrom failed");
                close(_socketfd);
                _socketfd=default_fd;
                return "";
            }
            else{
                InetAddr client_addr(clientaddr);
                std::cout<<"接收到消息: "<<buffer<<" 来自 "<<client_addr.PrintDebug()<<std::endl;
                return buffer;
            }
        }
        void Send(const std::string& message){
            // std::cout<<_ip<<std::endl;
            // std::cout<<_port<<std::endl;
            if(_socketfd==default_fd){
                std::cout<<"Error in sending message"<<std::endl;
                return;
            }
            
            if(sendto(_socketfd,message.c_str(),message.size(),0,(struct sockaddr*)&_serveraddr,sizeof(_serveraddr))==-1){
                std::cout<<"发送失败"<<std::endl;std::cout<<"发送消息: "<<message<<std::endl;
                perror("send failed");
                close(_socketfd);
                _socketfd=default_fd;
                return;
            }
            else{
                std::cout<<"发送成功"<<std::endl;std::cout<<"发送消息: "<<message<<std::endl;
            }
        }
        ~UdpClient(){
            if(_socketfd!=default_fd){
                close(_socketfd);
            }
        }
    private:
        int _socketfd;
        struct sockaddr_in _serveraddr;
        std::string _ip;
        uint16_t _port;
};